package com.kun.framework.core.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.kun.framework.core.AbstractApplication;
import com.kun.framework.core.enums.SvgInfoEnum;
import com.kun.framework.core.exception.Assert;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Paint;
import javafx.scene.shape.SVGPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 图标库
 *
 * @author gzc
 * @since 2024/8/7
 */
public class SvgStore {
    private static final Logger log = LoggerFactory.getLogger(SvgStore.class);

    private static final Map<SvgInfoEnum, Region> SVG_MAP = new HashMap<>(128);

    static {
        List<SvgInfoEnum> enumList = List.of(SvgInfoEnum.values());
        enumList.forEach(svgInfoEnum -> SVG_MAP.put(svgInfoEnum, new Region()));
        readSvg();
        System.out.println(JSONUtil.toJsonPrettyStr(SVG_MAP));
    }

    public static StackPane getSvg(SvgInfoEnum svgInfoEnum) {
        StackPane stackPane = new StackPane();
        stackPane.getChildren().add(SVG_MAP.get(svgInfoEnum));
        return stackPane;
    }

    public static StackPane getSvg(SvgInfoEnum svgInfoEnum, String color) {
        Region region = SVG_MAP.get(svgInfoEnum);
        StackPane stackPane = new StackPane();
        Background background = new Background(new BackgroundFill(Paint.valueOf(color), null, null));
        region.setBackground(background);
        stackPane.getChildren().add(region);
        return stackPane;
    }

    public static StackPane getSvgSizeAndColor(SvgInfoEnum svgInfoEnum, String color, double width, double height) {
        String style = StrUtil.format("-fx-background-color: {};-fx-pref-width: {};-fx-pref-height: {}",
                color, width, height);
        return getSvgByStyle(svgInfoEnum, style);
    }

    public static StackPane getSvgByStyle(SvgInfoEnum svgInfoEnum, String style) {
        Region region = SVG_MAP.get(svgInfoEnum);
        StackPane stackPane = new StackPane();
        region.setStyle(style);
        stackPane.getChildren().add(region);
        return stackPane;
    }

    /**
     * 读取svg
     */
    private static void readSvg() {
        SVG_MAP.forEach(((svgInfoEnum, region) -> {
            String svgContent = Assert.notBlank(loadSvgContent(svgInfoEnum.getSvgFilePath()), "svg文件【{}】 格式错误！", svgInfoEnum.getSvgFilePath());
            if (StrUtil.isNotBlank(svgContent)) {
                SVGPath svg = new SVGPath();
                svg.setContent(svgContent);
                region.setShape(svg);
            }
        }));
    }

    /**
     * 加载svg中的path，通过path值可直接转换成图片
     */
    public static String loadSvgContent(String pathName) {
        try {
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            //禁止DTD验证,防止网络阻塞
            builder.setEntityResolver(
                    (publicId, systemId) -> new InputSource(new StringReader(""))
            );
            // 读取svg xml数据
            InputStream resourceAsStream = ResourcesLoader.load(pathName);
            // 转换成document对象
            Document document = builder.parse(resourceAsStream);
            Node node = document.getElementsByTagName("path").item(0);
            return node.getAttributes().getNamedItem("d").getNodeValue();
        } catch (Exception e) {
            log.error("读取svg【" + pathName + "】发生异常->", e);
        }
        return "";
    }

    /**
     * 等比例缩放
     */
    private static void reSize(SVGPath svg, double width, double height) {
        double originalWidth = svg.prefWidth(-1);
        double originalHeight = svg.prefHeight(originalWidth);
        double scaleX = width / originalWidth;
        double scaleY = height / originalHeight;
        svg.setScaleX(scaleX);
        svg.setScaleY(scaleY);
    }


}
